Q:
I think I'm leaking io_object_t objects in my user space
I/O Kit code. I used the function IOObjectGetRetainCount
to find the retain count of those objects, but the values
I get back are larger than expected. Why is this? A:
There are actually two separate retain counts involved here. The first is the retain count of the underlying kernel object
represented by the io_object_t . The function IOObjectGetRetainCount returns this retain count by calling through to the
kernel. The second is the retain count of the io_object_t itself. An io_object_t is a wrapper
around a Mach port used to communicate between user space and the kernel, and Mach
ports have their own retain count. This also applies to the
other types derived from io_object_t : io_service_t, io_connect_t, io_iterator_t,
io_registry_entry_t, and io_enumerator_t . (These types are
defined in IOKit/IOTypes.h .) IOObjectRetain and IOObjectRelease operate on the retain
count of the io_object_t Mach port itself. This can be verified
by looking at IOKitLib.c in the IOKitUser project in
Darwin. So, the correct way to get the retain count of an io_object_t
is to use the Mach function mach_port_get_refs such as in
the snippet in Listing 1.
#include <IOKit/IOKitLib.h>#include <mach/mach_port.h>
kern_return_t kr;
unsigned int result;
io_object_t theObject;
io_name_t className;
kr = IOObjectGetClass(theObject, className);
if (KERN_SUCCESS == kr)
{
kern_return_t kr2;
kr2 = mach_port_get_refs(
mach_task_self(),
theObject,
MACH_PORT_RIGHT_SEND,
&result );
printf(
"ID: %#X, Class: %s, Retain Count: %d, Result=%#x\n",
theObject, className, result, kr2);
}
|
Listing 1. Getting the retain count of an io_object_t |
If you get the famous 0x10000003 (MACH_SEND_INVALID_DEST)
return code back from an IOKit.framework function, that's
referring to a stale io_object_t , not the underlying kernel
object. For more information on I/O Kit error codes, please
refer to Technical Q&A 1075.
[Sep 04 2002] |